package com.lframework.xingyun.basedata.impl.member;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lframework.starter.common.utils.Assert;
import com.lframework.starter.web.core.annotations.oplog.OpLog;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
import com.lframework.starter.web.core.utils.OpLogUtil;
import com.lframework.starter.web.core.utils.PageResultUtil;
import com.lframework.xingyun.basedata.bo.member.QueryMemberLevelDetailBo;
import com.lframework.xingyun.basedata.entity.Member;
import com.lframework.xingyun.basedata.entity.MemberLevel;
import com.lframework.xingyun.basedata.entity.MemberLevelDetail;
import com.lframework.xingyun.basedata.enums.BaseDataOpLogType;
import com.lframework.xingyun.basedata.mappers.MemberLevelDetailMapper;
import com.lframework.xingyun.basedata.service.member.MemberLevelService;
import com.lframework.xingyun.basedata.service.member.MemberService;
import com.lframework.xingyun.basedata.vo.member.CreateMemberLevelDetailVo;
import com.lframework.xingyun.basedata.service.member.MemberLevelDetailService;
import com.lframework.xingyun.basedata.vo.member.QueryMemberLevelDetailVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.Optional;

@Service
public class MemberLevelDetailServiceImpl extends BaseMpServiceImpl<MemberLevelDetailMapper, MemberLevelDetail> implements MemberLevelDetailService {

    /**
     * 查询列表
     * @param pageIndex
     * @param pageSize
     * @param vo
     * @return
     */
    @Override
    public PageResult<QueryMemberLevelDetailBo> query(Integer pageIndex, Integer pageSize, QueryMemberLevelDetailVo vo) {
        Assert.greaterThanZero(pageIndex);
        Assert.greaterThanZero(pageSize);

        IPage<QueryMemberLevelDetailBo> page = getBaseMapper().query(vo);

        return PageResultUtil.convert(page);
    }

    @OpLog(type = BaseDataOpLogType.class, name = "创建默认会员等级，memberId：{}, 会员等级名称：{}, 有效期：{}天, 开始时间：{}, 结算时间：{}",
            params = {"#memberId", "#levelName", "#effectiveDay", "#beginDate", "#endDate"})
    @Override
    public String createDefault(String memberId) {
        Member member = getThis(MemberService.class).findById(memberId);
        Assert.notNull(member, "会员不存在！");
        MemberLevel memberLevel = getThis(MemberLevelService.class).queryForever();
        Assert.notNull(memberLevel, "永久会员等级不存在！");

        DateTime beginDate = DateUtil.date();
        DateTime endDate = beginDate.offsetNew(DateField.DAY_OF_YEAR, memberLevel.getEffectiveDay());

        MemberLevelDetail data = new MemberLevelDetail();
        data.setMemberId(memberId);
        data.setLevelId(memberLevel.getId());
        data.setBeginDate(beginDate.toLocalDateTime());
        data.setEndDate(endDate.offsetNew(DateField.DAY_OF_YEAR, memberLevel.getEffectiveDay()).toLocalDateTime());
        data.setActivate(Boolean.TRUE);
        getBaseMapper().insert(data);

        OpLogUtil.setVariable("memberId", memberId);
        OpLogUtil.setVariable("levelName", memberLevel.getLevelName());
        OpLogUtil.setVariable("effectiveDay", memberLevel.getEffectiveDay());
        OpLogUtil.setVariable("beginDate", beginDate.toString("yyyy-MM-dd HH:mm:ss"));
        OpLogUtil.setVariable("endDate", endDate.toString("yyyy-MM-dd HH:mm:ss"));

        getThis(MemberLevelDetailService.class).autoActivate(data.getMemberId());

        return data.getId();
    }

    /**
     * 创建
     * @param vo
     * @return
     */
    @OpLog(type = BaseDataOpLogType.class, name = "设置会员等级，memberId：{}, 会员等级名称：{}, 有效期：{}天, 开始时间：{}, 结算时间：{}",
            params = {"#memberId", "#levelName", "#effectiveDay", "#beginDate", "#endDate"})
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String create(CreateMemberLevelDetailVo vo) {
        Member member = getThis(MemberService.class).findById(vo.getMemberId());
        Assert.notNull(member, "会员不存在！");
        MemberLevel level = getThis(MemberLevelService.class).findById(vo.getLevelId());
        Assert.notNull(level, "会员等级不存在！");
        Assert.state(level.getAvailable(), "会员等级已停用！");
        Assert.state(level.getEffectiveDay() > 0, "永久卡不能直接添加");
        QueryMemberLevelDetailBo lastActiveDetail = this.getBaseMapper()
                .queryLastActiveDetailByMemberId(vo.getMemberId());

        // 开始时间
        DateTime beginDate = Optional.ofNullable(vo.getBeginDate())
                .map(DateUtil::date).orElse(DateUtil.date());
        // 结束时间
        DateTime endDate = beginDate.offsetNew(DateField.DAY_OF_YEAR, level.getEffectiveDay());

        // 存在有效记录，开始时间为上一条记录的结束时间
        if (Objects.nonNull(lastActiveDetail)) {
            beginDate = DateUtil.date(lastActiveDetail.getEndDate());
            endDate = beginDate.offsetNew(DateField.DAY_OF_YEAR, level.getEffectiveDay());
        }

        MemberLevelDetail data = new MemberLevelDetail();
        data.setMemberId(vo.getMemberId());
        data.setLevelId(vo.getLevelId());
        data.setBeginDate(beginDate.toLocalDateTime());
        data.setEndDate(endDate.toLocalDateTime());
        data.setActivate(Boolean.FALSE);
        getBaseMapper().insert(data);

        getThis(MemberLevelDetailService.class).autoActivate(data.getMemberId());

        OpLogUtil.setVariable("memberId", vo.getMemberId());
        OpLogUtil.setVariable("levelName", level.getLevelName());
        OpLogUtil.setVariable("effectiveDay", level.getEffectiveDay());
        OpLogUtil.setVariable("beginDate", beginDate.toString("yyyy-MM-dd HH:mm:ss"));
        OpLogUtil.setVariable("endDate", endDate.toString("yyyy-MM-dd HH:mm:ss"));

        return data.getId();
    }

    /**
     * 自动生效会员等级明细
     * @param memberId 会员ID
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void autoActivate(String memberId) {
        // 查询当前可以生效的会员等级明细
        MemberLevelDetail detail = this.getBaseMapper().queryCanActiveDetailByMemberId(memberId, DateUtil.date().toLocalDateTime());
        if (Objects.nonNull(detail)) {
            // 失效当前生效的会员等级明细
            this.getBaseMapper().invalidateActiveDetail(memberId);
            // 生效当前查询到的会员等级明细
            this.getBaseMapper().activateDetail(detail.getId());
        }
    }

}
